// import pool from '../database/mysql.connection'
import {UserDto} from "./dto/user.dto";
import {BadRequestException, Inject, Injectable} from "@nestjs/common";
import * as mysql from 'mysql2/promise'
import {CreateUserDto} from "./dto/create-user.dto";

@Injectable()
export class UserRepository {
    private tableName = "user";

    constructor(
        @Inject('MYSQL_CONNECTION_POOL')
        private readonly pool: mysql.Pool,
    ) {
    }

    // 批量添加用户
    async createMany(users: CreateUserDto[]): Promise<UserDto[]> {
        if (!Array.isArray(users)) {
            throw new BadRequestException('Body must be an array');
        }
        if (users.length === 0) {
            throw new BadRequestException('不能添加空数组');
        }

        const placeholders = users.map(() => '(?,?,?)').join(", ");
        const values: any[] = [];

        users.forEach(user => {
            values.push(user.name, user.email, user.age);
        })

        const sql = `
            INSERT INTO ${this.tableName} (name, email, age)
            VALUES ${placeholders}
        `

        const [result] = await this.pool.execute(sql, values);
        const insertId = (result as any).insertId;

        // 查询刚才插入的数据
        const ids = Array.from({length: users.length}, (_, i) => insertId + i);
        const [rows] = await this.pool.execute(
            `SELECT *
             FROM ${this.tableName}
             where id IN (${ids.join(',')})`,
        );
        return rows as UserDto[];

    }

    // 查询所有用户
    async findAll(): Promise<UserDto[]> {
        const [rows] = await this.pool.execute(`SELECT name, age, email
                                                FROM ${this.tableName}`);
        return rows as UserDto[];
    }

    // 根据 ID 查询
    async findById(id: number): Promise<UserDto | null> {
        const [rows] = await this.pool.execute(`SELECT *
                                                FROM ${this.tableName}
                                                WHERE id = ?`, [id]);
        const result = rows as UserDto[];
        return result[0] || null;
    }

    // 写入用户
    async create(userData: Omit<UserDto, 'id'>): Promise<UserDto | null> {
        const [result] = await this.pool.execute(
            `INSERT INTO ${this.tableName} (name, email, age, password)
             VALUES (?, ?, ?, ?)`,
            [userData.name, userData.email, userData.age, userData.password],
        );
        const insertId = (result as any).insertId;
        return this.findById(insertId);
    }

    // 更新用户
    async update(id: number, userData: Partial<UserDto>): Promise<UserDto | null> {
        const fields: string[] = [];
        const values: (string | number)[] = [];

        if (userData.name) {
            fields.push('name = ? ');
            values.push(userData.name);
        }
        if (userData.email) {
            fields.push('email = ? ');
            values.push(userData.email);
        }
        if (userData.age) {
            fields.push('age = ? ');
            values.push(userData.age);
        }

        if (userData.password) {
            fields.push('password');
            values.push(userData.password);
        }

        // 最后一个是 ？ id
        values.push(id);

        await this.pool.execute(
            `UPDATE ${this.tableName}
             SET ${fields.join(',')}
             where id = ?`, values
        );

        return this.findById(id);
    }

    // 删除用户
    async remove(id: number): Promise<boolean> {
        const [result] = await this.pool.execute(`DELETE
                                                  FROM ${this.tableName}
                                                  where id = ?`, [id]);
        const affectedRows = (result as any).affectedRows;
        return affectedRows;
    }

    async findByUsername(username: string): Promise<UserDto | null> {
        const [result] = await this.pool.execute<any[]>(`SELECT name, email, age, password
                                                         FROM ${this.tableName}
                                                         where name = ?`, [username]);
        if (Array.isArray(result) && result.length > 0) {
            const user = result[0];
            return {
                id: user.id,
                name: user.name,
                email: user.email,
                age: user.age,
                password: user.password,
            };
        }

        return null;
    }

}